//
//  DatePickerView.swift
//  DemoSwift
//
//  Created by yaoxinpan on 2018/5/28.
//  Copyright © 2018年 yaoxp. All rights reserved.
//

import UIKit

protocol NibLoadable {}

extension NibLoadable {
//    static func loadViewFromNib() -> Self {
//        return Bundle.main.loadNibNamed("\(self)", owner: nil, options: nil)?.last as! Self
//    }
}

enum DateStyle {
    case all                    // 年月日时分秒
    case yearMonthDay           // 年月日
    case yearMonth           // 年月
    case hourMinuteSecond       // 时分秒
    case yearMonthDayHourMinute // 年月日时分
    case year
    case month
}

class DatePickerView: UIView, UIGestureRecognizerDelegate, UIPickerViewDelegate, UIPickerViewDataSource {

    // MARK: - 公开属性

    /// 最小的时间，默认是1970/1/1 00:00:00
    var minLimitDate: Date = Date(timeIntervalSince1970: 0) {
        didSet {

            if maxLimitDate < minLimitDate {

                minLimitDate = oldValue

            } else {

                if minLimitDate > scrollToDate {

                    scrollToDate = minLimitDate

                }
            }
        }
    }

    /// 最大的时间，默认是当前时间10年后
    var maxLimitDate: Date = Date(timeIntervalSinceNow: 60 * 60 * 24 * 365 * 20) {
        didSet {
            if maxLimitDate < minLimitDate {

                maxLimitDate = oldValue

            } else {

                if maxLimitDate < scrollToDate {

                    scrollToDate = maxLimitDate

                }
            }
        }
    }

    /// 默认显示的当前时间
    var scrollToDate: Date = Date() {
        didSet {

            if maxLimitDate < scrollToDate {

                scrollToDate = maxLimitDate

            }

            if minLimitDate > scrollToDate {

                scrollToDate = minLimitDate

            }

            yearLabel.text = String(scrollToDate.year)
        }
    }

    /// 确定按钮背景色，默认蓝色
    var sureButtonBackgroundColor: UIColor? {
        didSet {
            sureButton.backgroundColor = sureButtonBackgroundColor
        }
    }

    /// 确定按钮字体颜色，默认白色
    var sureButtonTitleColor: UIColor? {
        didSet {
            sureButton.setTitleColor(sureButtonTitleColor, for: .normal)
        }
    }

    /// 年 背景水印，设置无色可以隐藏
    var yearPlaceholderColor: UIColor? {
        didSet {
            yearLabel.textColor = yearPlaceholderColor
        }
    }
    
    var contentHeight: CGFloat = 304 + IphoneXMarginBottom
    
    var foreverBtn: UIButton = {
        let btn = UIButton.init()
        btn.setTitle(MMLocalizedString("permanent", comment: "永久"), for: .normal)
        btn.setTitle(MMLocalizedString("permanent", comment: "永久"), for: .highlighted)
        btn.titleLabel?.font = UIFont.init(name: Theme.PingFangSCRegular, size: 14)
        btn.setTitleColor(Theme.titleLabColor, for: .normal)
        btn.setTitleColor(Theme.titleLabColor, for: .highlighted)
        return btn
    }() //永久按钮 默认隐藏

    // MARK: - 私有属性
    ///底部view
     private var bottomView: UIView = {
       var tempView = UIView()
        tempView = UIView.init()
        tempView.backgroundColor = UIColor.white
        return tempView
     }()
    
    ///取消按钮
    private var cancelBtn: UIButton = {
        var btn = UIButton.init()
        btn.setTitle(MMLocalizedString("cancel", comment: "取消") , for: .normal)
        btn.setTitle(MMLocalizedString("cancel", comment: "取消"), for: .highlighted)
        btn.titleLabel?.font = UIFont.init(name: Theme.PingFangSCRegular, size: 16)
        btn.setTitleColor(Theme.mainColor, for: .normal)
        btn.setTitleColor(Theme.mainColor, for: .highlighted)
        
        return btn
    }()
    
    ///确定按钮
    private var sureButton: UIButton = {
        var btn = UIButton.init()
        btn.setTitle(MMLocalizedString("confirm", comment: "保存"), for: .normal)
        btn.setTitle(MMLocalizedString("confirm", comment: "保存"), for: .highlighted)
        btn.titleLabel?.font = UIFont.init(name: Theme.PingFangSCRegular, size: 16)
        btn.setTitleColor(Theme.mainColor, for: .normal)
        btn.setTitleColor(Theme.mainColor, for: .highlighted)
        return btn
    }()
    ///背景标题 2021
    private var yearLabel: UILabel = {
        let titleLab = UILabel.init()
        titleLab.backgroundColor = UIColor.clear
        titleLab.textColor = UIColor.init(hex: 0xeeeeee, alpha: 0.75)
        titleLab.font = UIFont.init(name: Theme.PingFangSCRegular, size: 110)
        titleLab.textAlignment = .center
        return titleLab
    }()
    
//    @IBOutlet private weak var bottomViewBottom: NSLayoutConstraint!
    ///选择器
    private var pickerView: UIPickerView = {
        let picker = UIPickerView.init()
        picker.backgroundColor = UIColor.clear
        return picker
    }()
    
    ///标题
    private var pickerTitleLab: UILabel = {
        let titleLab = UILabel.init()
        titleLab.backgroundColor = UIColor.clear
        titleLab.textColor = Theme.titleLabColor
        titleLab.font = UIFont.init(name: Theme.PingFangSCMedium, size: 14)
        titleLab.textAlignment = .center
        return titleLab
    }()
    
    private var lineView: UIView = {
        let tempView = UIView.init()
        tempView.backgroundColor = Theme.eColor
        return tempView

    }()
    private var lineViewBottom: UIView = {
        let tempView = UIView.init()
        tempView.backgroundColor = Theme.eColor
        return tempView

    }()
    private var componentsArray = [[String: [Int]]]()

    /// 显示的时间样式
    private var style: DateStyle = .all

    private let yearKey = MMLocalizedString("year", comment: "年")
    private let monthKey = MMLocalizedString("month", comment: "月")
    private let dayKey = MMLocalizedString("day", comment: "日")
    private let hourKey = "时"
    private let minuteKey = "分"
    private let secondKey = "秒"
    
    private var completionHandler: (_ date: Date?) -> Void = {_ in }

    ///
    /// - Parameters:
    ///   - style: 类型
    ///   - scrollToDate: 滚动到的时间，如果不设刚是当前时间
    /// - Returns: 新的DatePickerView
    class func datePicker(style: DateStyle = .all, scrollToDate: Date = Date(), completionHandler: @escaping (_ date: Date?) -> Void) -> DatePickerView {

        let view: DatePickerView = DatePickerView.init() //DatePickerView.loadViewFromNib()

        view.style = style

        view.completionHandler = completionHandler

        view.scrollToDate = scrollToDate

        view.setupUI()

        view.setupData()
        return view
    }
    
    ///选择永久
    @objc func foreverBtnAction(_ sender: Any) {
        let string = "1970-01-01"
        completionHandler(Date.date(string, formatter: "yyyy-MM-dd"))
        dismiss()
    }
    
    func show() {
        if self.foreverBtn.isHidden == false {
            contentHeight = contentHeight + 40
            self.foreverBtn.snp.updateConstraints { (make) in
                make.height.equalTo(40)
            }
        }
        self.bottomView.snp.updateConstraints { (make) in
            make.height.equalTo(contentHeight)
        }
        setupData()
        UIApplication.shared.keyWindow!.addSubview(self)
        self.frame = UIScreen.main.bounds
        self.bottomView.snp.updateConstraints { (make) in
            make.bottom.equalTo(contentHeight)
        }
        self.layoutIfNeeded()
        bottomView.roundCorners(corners: UIRectCorner(arrayLiteral: [.topLeft, .topRight]), radius: 10)//顶部圆角
        UIView.animate(withDuration: 0.24, animations: {
            self.bottomView.snp.updateConstraints { (make) in
                make.bottom.equalTo(0)
            }
            self.backgroundColor = UIColor.init(hex: 0x000000, alpha: 0.5)
            
            self.layoutIfNeeded()
        }, completion: { (finish) in
            self.scrollTo(self.scrollToDate)
        })
    }
    
    @objc func dismiss() {
        UIView.animate(withDuration: 0.24, animations: {
            self.bottomView.snp.updateConstraints { (make) in
                make.bottom.equalTo(self.contentHeight)
            }
            self.backgroundColor = UIColor.init(hex: 0x000000, alpha: 0)
            
            self.layoutIfNeeded()
            
        }, completion: { (finished) in
            
            self.removeFromSuperview()
            
        })
    }

    @objc func onSureButtonAction() {
        let curDate = currentDate()
        let curCount = curDate?.timeIntervalSince1970 ?? 0
        let minCount = self.minLimitDate.timeIntervalSince1970
        if (self.style != .year &&
            self.style != .month) {
            if curCount < minCount {
                return
            }
        }
        completionHandler(currentDate())
        dismiss()
    }
    
    @objc func dismissAction() {
        self.dismiss()
    }
}

/*
extension DatePickerView {
    public struct DateStyle: OptionSet {
        let rawValue: Int

        static let second   = DateStyle(rawValue: 1 << 0)
        static let minute   = DateStyle(rawValue: 1 << 1)
        static let hour     = DateStyle(rawValue: 1 << 2)
        static let day      = DateStyle(rawValue: 1 << 3)
        static let month    = DateStyle(rawValue: 1 << 4)
        static let year     = DateStyle(rawValue: 1 << 5)

        static let all: DateStyle = [.year, .month, .day, .hour, .minute, .second]
    }
}
 */

extension DatePickerView {
    private func setupUI() {
        self.foreverBtn.titleLabel?.font = UIFont.init(name: Theme.PingFangSCMedium, size: 14)
        self.foreverBtn.setTitleColor(Theme.titleLabColor, for: .normal)
        self.foreverBtn.setTitleColor(Theme.titleLabColor, for: .normal)
        self.foreverBtn.isHidden = true
        self.foreverBtn.setBackgroundImage(UIImage.image(withColor: Theme.whiteColor), for: .normal)
        self.foreverBtn.setBackgroundImage(UIImage.image(withColor: Theme.F5Color), for: .highlighted)
        
        self.pickerTitleLab.text = MMLocalizedString("add_select_date", comment: "选择日期")
        self.pickerTitleLab.font = UIFont.init(name: Theme.PingFangSCMedium, size: 16)
        self.pickerTitleLab.textColor = UIColor.init(hex: 0x111A34)
        backgroundColor = UIColor.init(hex: 0x000000, alpha: 0)
        
        self.addSubview(bottomView)
        bottomView.addSubview(cancelBtn)
        bottomView.addSubview(sureButton)
        bottomView.addSubview(pickerTitleLab)
        bottomView.addSubview(lineView)
        bottomView.addSubview(yearLabel)
        bottomView.addSubview(pickerView)
        bottomView.addSubview(foreverBtn)
        foreverBtn.addSubview(lineViewBottom)
        
        self.addSnpLayout()

        let tap = UITapGestureRecognizer(target: self, action: #selector(dismiss))
        tap.delegate = self
        addGestureRecognizer(tap)

        pickerView.delegate = self
        pickerView.dataSource = self
        cancelBtn.addTarget(self, action: #selector(dismissAction), for: .touchUpInside)
        sureButton.addTarget(self, action: #selector(onSureButtonAction), for: .touchUpInside)
        foreverBtn.addTarget(self, action: #selector(foreverBtnAction), for: .touchUpInside)
    }
    
    ///布局
    func addSnpLayout() {
        self.bottomView.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.right.equalTo(0)
            make.height.equalTo(contentHeight)
            make.bottom.equalTo(contentHeight)
        }
        
        self.cancelBtn.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.top.equalTo(0)
            make.size.equalTo(CGSize.init(width: 56, height: 56))
        }
        self.sureButton.snp.makeConstraints { (make) in
            make.right.equalTo(0)
            make.top.equalTo(0)
            make.size.equalTo(CGSize.init(width: 56, height: 56))
        }
        
        self.pickerTitleLab.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.right.equalTo(0)
            make.top.equalTo(0)
            make.height.equalTo(56)
        }
        
        lineView.snp.makeConstraints { (make) in
            make.left.right.equalTo(0)
            make.top.equalTo(56)
            make.height.equalTo(0.5)
        }
        
        self.yearLabel.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.right.equalTo(0)
            make.top.equalTo(56)
        }
        
        self.pickerView.snp.makeConstraints { (make) in
            make.width.equalTo(kScreenWidth)
            make.height.equalTo(250)
            make.centerX.equalTo(self.yearLabel.snp.centerX)
            make.centerY.equalTo(self.yearLabel.snp.centerY)
        }
        
        self.foreverBtn.snp.makeConstraints { (make) in
            make.left.equalTo(0)
            make.right.equalTo(0)
            make.top.equalTo(self.yearLabel.snp.bottom)
            make.height.equalTo(0)
            make.bottom.equalTo(bottomView.snp.bottom).offset(-IphoneXMarginBottom)
        }
        
        self.lineViewBottom.snp.makeConstraints { (make) in
            make.left.right.top.equalTo(0)
            make.height.equalTo(0.5)
        }
    }
    
    

    private func setupData() {
        componentsArray = [Dictionary]()

        switch style {
        case .all:
            initDataWithAllStyle()
        case .year:
            initDataWithYearStyle()
        case .month:
            initDataWithMonthStyle()
        case .yearMonth://年月
            initDataWithYearMonthStyle()
            
        case .yearMonthDay:

            initDataWithYearMonthDayStyle()
      
        case .hourMinuteSecond:

            initDataWithHourMinuteSecondStyle()

        case .yearMonthDayHourMinute:

            initDataWithYearMonthDayHourMinuteStyle()

        }
    }

    private func currentDate() -> Date? {
        var result = [Int]()
        
        for index in 0..<pickerView.numberOfComponents {
            let tempArr = componentsArray[index].values.first ?? []
            let tempIndex = pickerView.selectedRow(inComponent: index)
            if tempArr.count > tempIndex {
                let temp = componentsArray[index].values.first![tempIndex]
                result.append(temp)
            }
        }
        
        switch style {
            
        case .all:
            
            guard result.count == 6 else { return nil }
            
            let dateStr = String(result[0]) + "-" + String(result[1]) + "-" + String(result[2]) + " " +
            String(result[3]) + ":" + String(result[4]) + ":" + String(result[5])
            
            return Date.date(dateStr, formatter: "yyyy-MM-dd HH:mm:ss")
            
            
        case .yearMonth:
            
            guard result.count == 2 else { return nil }
            
            var tempMonth = String(format: "%d", result[1])
            if tempMonth.count < 2 {
                tempMonth = String(format: "0%d", result[1])
            }
            let dateStr = String(result[0]) + "-" + tempMonth
            let tempDate = Date.date(dateStr, formatter: "yyyy-MM")
            return tempDate
            
        case .yearMonthDay:
            
            guard result.count == 3 else { return nil }
            
            var tempMonth = String(format: "%d", result[1])
            if tempMonth.count < 2 {
                tempMonth = String(format: "0%d", result[1])
            }
            let dateStr = String(result[0]) + "-" + tempMonth + "-" + String(result[2])
            let tempDate = Date.date(dateStr, formatter: "yyyy-MM-dd")
            return tempDate //Date.date(dateStr, formatter: "yyyy-MM-dd")
            
        case .hourMinuteSecond:
            
            guard result.count == 3 else { return nil }
            
            let dateStr = String(result[0]) + ":" + String(result[1]) + ":" + String(result[2])
            
            return Date.date(dateStr, formatter: "HH:mm:ss")
            
        case .yearMonthDayHourMinute:
            
            guard result.count == 5 else { return nil }
            
            let dateStr = String(result[0]) + "-" + String(result[1]) + "-" + String(result[2]) + " " +
            String(result[3]) + ":" + String(result[4])
            
            return Date.date(dateStr, formatter: "yyyy-MM-dd HH:mm")
            
        case .year:
            guard result.count == 1 else { return nil }
            let dateStr = String(result[0])
            return Date.date(dateStr, formatter: "yyyy")
        case .month:
            guard result.count == 1 else { return nil }
            let dateStr = String(result[0])
            return Date.date(dateStr, formatter: "MM")
        }
        
    }

}

// MARK: - scroll to date
extension DatePickerView {
    private func scrollTo(_ date: Date) {

        var scrollToDate = date

        if scrollToDate > maxLimitDate {
            scrollToDate = maxLimitDate
        }

        if scrollToDate < minLimitDate {
            scrollToDate = minLimitDate
        }

        switch style {
        case .all:
            allStyleScrollTo(scrollToDate)
        case .yearMonth:
            yearMonthStyleScrollTo(scrollToDate)
        case .yearMonthDay:
            yearMonthDayStyleScrollTo(scrollToDate)
        case .hourMinuteSecond:
            hourMinuteSecondStyleScrollTo(scrollToDate)
        case .yearMonthDayHourMinute:
            yearMonthDayHourMinuteStyleScrollTo(scrollToDate)
        case .year:
            yearStyleScrollTo(scrollToDate)
        case .month:
            monthStyleScrollTo(scrollToDate)
        }

    }

    private func allStyleScrollTo(_ date: Date) {

        guard componentsArray.count == 6 else {
            return
        }

        if let yearIndex = componentsArray[0][yearKey]?.firstIndex(of: date.year) {
            pickerView.selectRow(yearIndex, inComponent: 0, animated: true)
        }

        if let monthIndex = componentsArray[1][monthKey]?.firstIndex(of: date.month) {
            pickerView.selectRow(monthIndex, inComponent: 1, animated: true)
        }

        if let dayIndex = componentsArray[2][dayKey]?.firstIndex(of: date.day) {
            pickerView.selectRow(dayIndex, inComponent: 2, animated: true)
        }

        if let hourIndex = componentsArray[3][hourKey]?.firstIndex(of: date.hour) {
            pickerView.selectRow(hourIndex, inComponent: 3, animated: true)
        }

        if let minuteIndex = componentsArray[4][minuteKey]?.firstIndex(of: date.minute) {
            pickerView.selectRow(minuteIndex, inComponent: 4, animated: true)
        }

        if let secondIndex = componentsArray[5][secondKey]?.firstIndex(of: date.second) {
            pickerView.selectRow(secondIndex, inComponent: 5, animated: true)
        }
    }
    
    private func yearStyleScrollTo(_ date: Date) {
        guard componentsArray.count == 1 else {
            return
        }
        if let yearIndex = componentsArray[0][yearKey]?.firstIndex(of: date.year) {
            pickerView.selectRow(yearIndex, inComponent: 0, animated: true)
        }
    }
    
    
    private func monthStyleScrollTo(_ date: Date) {
        guard componentsArray.count == 1 else {
            return
        }
        if let monthIndex = componentsArray[0][monthKey]?.firstIndex(of: date.month) {
            pickerView.selectRow(monthIndex, inComponent: 0, animated: true)
        }
    }

    private func yearMonthStyleScrollTo(_ date: Date) {

        guard componentsArray.count == 2 else {
            return
        }

        if let yearIndex = componentsArray[0][yearKey]?.firstIndex(of: date.year) {
            pickerView.selectRow(yearIndex, inComponent: 0, animated: true)
        }

        if let monthIndex = componentsArray[1][monthKey]?.firstIndex(of: date.month) {
            pickerView.selectRow(monthIndex, inComponent: 1, animated: true)
        }
    }

    private func yearMonthDayStyleScrollTo(_ date: Date) {

        guard componentsArray.count == 3 else {
            return
        }

        if let yearIndex = componentsArray[0][yearKey]?.firstIndex(of: date.year) {
            pickerView.selectRow(yearIndex, inComponent: 0, animated: true)
        }

        if let monthIndex = componentsArray[1][monthKey]?.firstIndex(of: date.month) {
            pickerView.selectRow(monthIndex, inComponent: 1, animated: true)
        }

        if let dayIndex = componentsArray[2][dayKey]?.firstIndex(of: date.day) {
            pickerView.selectRow(dayIndex, inComponent: 2, animated: true)
        }
    }

    private func hourMinuteSecondStyleScrollTo(_ date: Date) {

        guard componentsArray.count == 3 else {
            return
        }

        if let hourIndex = componentsArray[0][hourKey]?.firstIndex(of: date.hour) {
            pickerView.selectRow(hourIndex, inComponent: 0, animated: true)
        }

        if let minuteIndex = componentsArray[1][minuteKey]?.firstIndex(of: date.minute) {
            pickerView.selectRow(minuteIndex, inComponent: 1, animated: true)
        }

        if let secondIndex = componentsArray[2][secondKey]?.firstIndex(of: date.second) {
            pickerView.selectRow(secondIndex, inComponent: 2, animated: true)
        }
    }

    private func yearMonthDayHourMinuteStyleScrollTo(_ date: Date) {

        guard componentsArray.count == 5 else {
            return
        }

        if let yearIndex = componentsArray[0][yearKey]?.firstIndex(of: date.year) {
            pickerView.selectRow(yearIndex, inComponent: 0, animated: true)
        }

        if let monthIndex = componentsArray[1][monthKey]?.firstIndex(of: date.month) {
            pickerView.selectRow(monthIndex, inComponent: 1, animated: true)
        }

        if let dayIndex = componentsArray[2][dayKey]?.firstIndex(of: date.day) {
            pickerView.selectRow(dayIndex, inComponent: 2, animated: true)
        }

        if let hourIndex = componentsArray[3][hourKey]?.firstIndex(of: date.hour) {
            pickerView.selectRow(hourIndex, inComponent: 3, animated: true)
        }

        if let minuteIndex = componentsArray[4][minuteKey]?.firstIndex(of: date.minute) {
            pickerView.selectRow(minuteIndex, inComponent: 4, animated: true)
        }

    }
}

// MARK: - init data
extension DatePickerView {
    
    private func initDataWithYearStyle(){
        componentsArray.append([yearKey: Array(minLimitDate.year...maxLimitDate.year)])
    }
    
    private func initDataWithMonthStyle(){
        //取最小的日期的月份
//        let minMonth = self.minLimitDate.month
        componentsArray.append([monthKey: Array(1...12)])
    }
    private func initDataWithAllStyle() {
        componentsArray.append([yearKey: Array(minLimitDate.year...maxLimitDate.year)])

        if minLimitDate.haveSameYear(maxLimitDate) {
            componentsArray.append([monthKey: Array(minLimitDate.month...maxLimitDate.month)])
        } else {
            componentsArray.append([monthKey: Array(1...12)])
        }

        if minLimitDate.haveSameYearAndMonth(maxLimitDate) {
            componentsArray.append([dayKey: Array(minLimitDate.day...maxLimitDate.day)])
        } else {
            componentsArray.append([dayKey: Array(1...scrollToDate.numberOfDaysInMonth())])
        }

        if minLimitDate.haveSameYearMonthAndDay(maxLimitDate) {
            componentsArray.append([hourKey: Array(minLimitDate.day...maxLimitDate.day)])
        } else {
            componentsArray.append([hourKey: Array(0...23)])
        }

        if minLimitDate.haveSameYearMonthDayAndHour(maxLimitDate) {
            componentsArray.append([minuteKey: Array(minLimitDate.minute...maxLimitDate.minute)])
        } else {
            componentsArray.append([minuteKey: Array(0...59)])
        }

        if minLimitDate.haveSameYearMonthDayHourAndMinute(maxLimitDate) {
            componentsArray.append([secondKey: Array(minLimitDate.minute...maxLimitDate.minute)])
        } else {
            componentsArray.append([secondKey: Array(0...59)])
        }

    }
    
    
    //年月
    private func initDataWithYearMonthStyle() {
        componentsArray.append([yearKey: Array(minLimitDate.year...maxLimitDate.year)])

        if minLimitDate.haveSameYear(maxLimitDate) {
            componentsArray.append([monthKey: Array(minLimitDate.month...maxLimitDate.month)])
        } else {
            componentsArray.append([monthKey: Array(1...12)])
        }
    }
    
    private func initDataWithYearMonthDayStyle() {
        componentsArray.append([yearKey: Array(minLimitDate.year...maxLimitDate.year)])

        if minLimitDate.haveSameYear(maxLimitDate) {
            componentsArray.append([monthKey: Array(minLimitDate.month...maxLimitDate.month)])
        } else {
            componentsArray.append([monthKey: Array(1...12)])
        }

        if minLimitDate.haveSameYearAndMonth(maxLimitDate) {
            componentsArray.append([dayKey: Array(minLimitDate.day...maxLimitDate.day)])
        } else {
            componentsArray.append([dayKey: Array(1...scrollToDate.numberOfDaysInMonth())])
        }
    }

 
    
    private func initDataWithHourMinuteSecondStyle() {

        if let date = Date.date("00:00:00", formatter: "HH:mm:ss") {
            minLimitDate = date
        }

        if let date = Date.date("23:59:59", formatter: "HH:mm:ss") {
            maxLimitDate = date
        }

        componentsArray.append([hourKey: Array(minLimitDate.hour...maxLimitDate.hour)])

        if minLimitDate.haveSameYearMonthDayAndHour(maxLimitDate) {
            componentsArray.append([minuteKey: Array(minLimitDate.minute...maxLimitDate.minute)])
        } else {
            componentsArray.append([minuteKey: Array(0...59)])
        }

        if minLimitDate.haveSameYearMonthDayHourAndMinute(maxLimitDate) {
            componentsArray.append([secondKey: Array(minLimitDate.second...maxLimitDate.second)])
        } else {
            componentsArray.append([secondKey: Array(0...59)])
        }
    }

    private func initDataWithYearMonthDayHourMinuteStyle() {
        componentsArray.append([yearKey: Array(minLimitDate.year...maxLimitDate.year)])

        if minLimitDate.haveSameYear(maxLimitDate) {
            componentsArray.append([monthKey: Array(minLimitDate.month...maxLimitDate.month)])
        } else {
            componentsArray.append([monthKey: Array(1...12)])
        }

        if minLimitDate.haveSameYearAndMonth(maxLimitDate) {
            componentsArray.append([dayKey: Array(minLimitDate.day...maxLimitDate.day)])
        } else {
            componentsArray.append([dayKey: Array(1...scrollToDate.numberOfDaysInMonth())])
        }

        if minLimitDate.haveSameYearMonthAndDay(maxLimitDate) {
            componentsArray.append([hourKey: Array(minLimitDate.day...maxLimitDate.day)])
        } else {
            componentsArray.append([hourKey: Array(0...23)])
        }

        if minLimitDate.haveSameYearMonthDayAndHour(maxLimitDate) {
            componentsArray.append([minuteKey: Array(minLimitDate.minute...maxLimitDate.minute)])
        } else {
            componentsArray.append([minuteKey: Array(0...59)])
        }
    }
}

// MARK: - UIGestureRecognizerDelegate
extension DatePickerView {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        guard let touchView = touch.view else { return false }

        if touchView.isDescendant(of: bottomView) {
            // 点击的view是否是bottomView或者bottomView的子视图
            return false
        }

        return true
    }
}

// MARK: - UIPickerViewDelegate, UIPickerViewDataSource
extension DatePickerView {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return componentsArray.count
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if let array = componentsArray[component].values.first {
            return array.count
        }
        return 0
    }

    func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 40
    }

    func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {

        var title: String = " "
        let dic = componentsArray[component]
        if let key = dic.keys.first {
            let data = dic[key]
            if XTManageCenter.getAppleLanguages() == AppLanguage.english.rawValue {
                title = String(data![row])
            }else{
                title = String(data![row]) // + key
            }
            
        }

        if let label = view as? UILabel {
            label.text = title
            return label
        }

        let label = UILabel()
        label.textAlignment = .center
        label.font = UIFont.init(name: Theme.PingFangSCMedium, size: 18)
        label.text = title
        label.sizeToFit()
        return label
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        // 月分变化了，天数要跟着变化.年份变化了，如果是2月,天数也可能变化

        func scrollToValidTimeRange() {
            // 检查当前时间是否在最大和最小时间之前
            if let currentDate = currentDate() {

                if currentDate > maxLimitDate {
                    // 超过最大值，则滚回最大值
                    scrollTo(maxLimitDate)

                } else if currentDate < minLimitDate {
                    // 小于最小值，刚滚回最小值
                    scrollTo(minLimitDate)
                }
            }
        }

        guard let key = componentsArray[component].keys.first, key == yearKey || key == monthKey else {
            // 只是滚动年或者月时，才需要处理天数的变化
            scrollToValidTimeRange()
            return
        }

        let yearIndex = pickerView.selectedRow(inComponent: 0)
        if yearIndex < 0 {
            scrollToValidTimeRange()

            return
        }

        if key == yearKey {
            // 更新年份水印
            let year = componentsArray[0][yearKey]![yearIndex]      // 年份

            yearLabel.text = String(year)
        }
        
        if self.style != .year && self.style != .month {
            if key == yearKey && yearKey != "" && pickerView.selectedRow(inComponent: component + 1) != 1 {
                // 滚动年，月分不是2月时，不需要处理天数变化
                scrollToValidTimeRange()

                return
            }

            let monthIndex = pickerView.selectedRow(inComponent: 1)
            if monthIndex < 0 {

                scrollToValidTimeRange()

                return
            }

            let year = componentsArray[0][yearKey]![yearIndex]      // 年份
            let month = componentsArray[1][monthKey]![monthIndex]   // 月份
             
            if key == monthKey{
                scrollToValidTimeRange()
                return
            }

            guard let date = Date.date(String(year) + "-" + String(month), formatter: "yyyy-MM") else {
                scrollToValidTimeRange()
                return
            }

            let numberOfDays = date.numberOfDaysInMonth() // 当前月的天数
            if numberOfDays != 0 && numberOfDays == componentsArray[2][dayKey]!.count {
                // 天数没有变化，不需要任何操作
                scrollToValidTimeRange()
                return
            }

            let newDayDic = [dayKey: Array(1...numberOfDays)] // 新的天数数据

            componentsArray.replaceSubrange(2...2, with: [newDayDic])

            pickerView.reloadComponent(2)
        }else{
            pickerView.reloadComponent(0)
        }
        scrollToValidTimeRange()
    }
}
